package modules.lock.producers3;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Lock的 生产者和消费者  通过Condition可以精准通知唤醒
 * 票 - 资源类
 * 多线程下顺序调用
 * 适合 生产线 -》 下单-》支付-》交易 -》物流
 * @author shengren.yan
 * @create 2021-03-05
 */
public class Ticket5 {

    private int number = 0;

    // Lock版本的 生产者与消费
    Lock lock = new ReentrantLock();
    Condition condition1 = lock.newCondition();
    Condition condition2 = lock.newCondition();
    Condition condition3 = lock.newCondition();
    // 状态分为  1 condition1执行  2 condition2执行  3 condition3执行
    private int state = 1;

    // A方法
    public void doA(){
        lock.lock();
        // 业务 - 判断 - 执行 - 通知
        try {
            while(state != 1){
                condition1.await(); //等待
            }
            System.out.println(Thread.currentThread().getName() + "执行："+ state);
            state = 2;
            condition2.signal();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    // B方法
    public void doB(){
        lock.lock();
        try {
            while(state != 2){
                condition2.await(); //等待
            }
            System.out.println(Thread.currentThread().getName() + "执行："+ state);
            state = 3;
            condition3.signal();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    // C方法
    public void doC(){
        lock.lock();
        try {
            while(state != 3){
                condition3.await(); //等待
            }
            System.out.println(Thread.currentThread().getName() + "执行："+ state);
            state = 1;
            condition1.signal();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }


}